﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using XboxUserInterface.Keys;
using XboxUserInterface.Properties;
using XboxUserInterface.Settings;
using XboxUserInterface.Variables;
using MyCustomControls;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using System.Threading;

namespace XboxUserInterface.Forms
{
    public partial class Service : Form
    {
        /// <summary>
        /// List of threads monitoring functions
        /// </summary>
        private List<Thread> threads;

        /// <summary>
        /// ControllerHelper to monitor data
        /// </summary>
        ControllerHelper controller = new ControllerHelper();

        /// <summary>
        /// Creates a new instance of the service and hides it from the user.
        /// </summary>
        public Service()
        {
            InitializeComponent();
            this.Hide();
        }

        #region Event Handlers

        /// <summary>
        /// Loads the schemes into the context menu for the tray icon on opening the menu
        /// </summary>
        /// <param name="sender">Service making the call</param>
        /// <param name="e">Information for the call</param>
        private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
        {
            selectActive.DropDownItems.Clear();
            foreach (KeyMap m in Globals.Schemes)
            {
                SchemeDropDownItem t = new SchemeDropDownItem();

                t.Scheme = m;
                t.Name = m.SchemeName;
                t.Text = m.SchemeName;
                t.Visible = true;
                if (m.Active)
                    t.Checked = true;
                t.Click += new EventHandler(t_Click);

                selectActive.DropDownItems.Add(t);
            }
        }

        /// <summary>
        /// Sets the active scheme to the one clicked in the context menu.
        /// </summary>
        /// <param name="sender">Service making the call</param>
        /// <param name="e">Information for the call</param>
        void t_Click(object sender, EventArgs e)
        {
            SchemeDropDownItem t = (SchemeDropDownItem)sender;
            if (!t.Checked)
                Globals.Active = (KeyMap)t.Scheme;

            t.Checked = true;
        }

        /// <summary>
        /// Opens a new Settings form to modify settings for individual schemes
        /// </summary>        
        /// <param name="sender">Service making the call</param>
        /// <param name="e">Information for the call</param>
        private void openSettings_Click(object sender, EventArgs e)
        {
            Schemes s = new Schemes();
            s.Show();
        }

        /// <summary>
        /// Closes the application
        /// </summary>
        /// <param name="sender">Service making the call</param>
        /// <param name="e">Information for the call</param>
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (Thread t in threads)
                t.Abort();
            this.Close();
            Application.Exit();
        }

        /// <summary>
        /// Opens the settings dialog on double clicking the tray icon
        /// </summary>
        /// <param name="sender">Service making the call</param>
        /// <param name="e">Information for the call</param>
        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            openSettings_Click(sender, e);
        }

        #endregion

        /// <summary>
        /// Creates the threads and begins monitoring the controller on loading the form
        /// </summary>
        /// <param name="sender">Service making the call</param>
        /// <param name="e">Information for the call</param>
        private void Service_Load(object sender, EventArgs e)
        {
            WindowState = FormWindowState.Minimized;
            ShowInTaskbar = false;

            controller.Buttons = GamePad.GetState(PlayerIndex.One).Buttons;
            controller.DPad = GamePad.GetState(PlayerIndex.One).DPad;
            controller.ThumbSticks = GamePad.GetState(PlayerIndex.One).ThumbSticks;
            controller.Triggers = GamePad.GetState(PlayerIndex.One).Triggers;

            threads = new List<Thread>();

            createThreads();

            foreach (Thread t in threads)
                t.Start();
        }

        /// <summary>
        /// Shows the About form for the application
        /// </summary>
        /// <param name="sender">This form</param>
        /// <param name="e">Information about the call</param>
        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            About a = new About();
            a.Show();
        }

        #region Threading

        /// <summary>
        /// Creates the threads for monitoring the controller
        /// </summary>
        private void createThreads()
        {
            Thread buttons = new Thread(new ThreadStart(buttonWatch));
            Thread dPad = new Thread(new ThreadStart(dPadWatch));
            Thread tSticks = new Thread(new ThreadStart(tStickWatch));
            Thread triggers = new Thread(new ThreadStart(triggerWatch));

            threads.Add(buttons);
            threads.Add(dPad);
            threads.Add(tSticks);
            threads.Add(triggers);
        }

        /// <summary>
        /// Delegate for monitoring digital buttons on the controller
        /// </summary>
        private void buttonWatch()
        {
            while (true)
            {
                GamePadButtons b = GamePad.GetState(PlayerIndex.One).Buttons;
                if (!object.Equals(controller.Buttons, b))
                    controller.Buttons = b;

                Thread.Sleep(70);
            }
        }

        /// <summary>
        /// Delegate for monitoring the D-Pad on the controller
        /// </summary>
        private void dPadWatch()
        {
            while (true)
            {
                GamePadDPad d = GamePad.GetState(PlayerIndex.One).DPad;
                if (!object.Equals(controller.DPad, d))
                    controller.DPad = d;

                Thread.Sleep(70);
            }
        }

        /// <summary>
        /// Delegate for monitoring the thumb sticks on the controller
        /// </summary>
        private void tStickWatch()
        {
            while (true)
            {
                controller.ThumbSticks = GamePad.GetState(PlayerIndex.One).ThumbSticks;

                Thread.Sleep(10);
            }
        }

        /// <summary>
        /// Delegate for monitoring the analog triggers on the controller
        /// </summary>
        private void triggerWatch()
        {
            while (true)
            {
                GamePadTriggers t = GamePad.GetState(PlayerIndex.One).Triggers;
                if (!object.Equals(controller.Triggers, t))
                    controller.Triggers = t;

                Thread.Sleep(70);
            }
        }

        #endregion

    }
}
